﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Point = System.Windows.Point;

namespace FishSimulation.Model {
    public class Pond : ModelBase {        
        double _WaterTemp = 70;

        public ObservableCollection<Cord> Points {
            get;
            set;
        }
        
        /// <summary>
        /// Water temperature in degrees fahrenheit
        /// </summary>
        public double WaterTemp {
            get {
                return _WaterTemp;
            }
            set {
                if (_WaterTemp != value) {
                    _WaterTemp = value;
                    this.OnPropertyChanged("WaterTemp");
                }
            }
        }

        public Pond() { 
        
        }
                        
        /// <summary>
        /// Picks a random point inside the pond
        /// </summary>
        /// <returns></returns>
        public Cord GetRandomCord() {
            Cord c = null;
            if (this.Points != null && this.Points.Count >= 3) {
                var temp = new List<Cord>();
                //copy the array
                foreach (var p in this.Points) {
                    temp.Add(new Cord(p.X, p.Y));
                }
                
                var i1 = temp[Utils.RandomInt(0, temp.Count - 1)];
                temp.Remove(i1);

                var i2 = temp[Utils.RandomInt(0, temp.Count - 1)];
                temp.Remove(i2);

                var i3 = temp[Utils.RandomInt(0, temp.Count - 1)];
                temp.Remove(i3);

                var box = Utils.GetBoundingBox(i1, i2, i3);
                while (true) {
                    c = Utils.RandomCord(box);
                    if (this.InPond(c))
                        break;
                }
            }
            return c;
        } 

        public bool InPond(Cord p) {
            if (this.Points == null) return false;

            Point p1, p2;

            bool inside = false;

            var poly = this.Points.ToArray();

            if (poly.Length < 3) {
                return inside;
            }

            Point oldPoint = new Point(
            poly[poly.Length - 1].X, poly[poly.Length - 1].Y);

            for (int i = 0; i < poly.Length; i++) {
                Point newPoint = new Point(poly[i].X, poly[i].Y);

                if (newPoint.X > oldPoint.X) {
                    p1 = oldPoint;
                    p2 = newPoint;
                }
                else {
                    p1 = newPoint;
                    p2 = oldPoint;
                }

                if ((newPoint.X < p.X) == (p.X <= oldPoint.X)
                && ((long)p.Y - (long)p1.Y) * (long)(p2.X - p1.X)
                 < ((long)p2.Y - (long)p1.Y) * (long)(p.X - p1.X)) {
                    inside = !inside;
                }

                oldPoint = newPoint;
            }

            return inside;
        }

        public override string ToString() {
            return "Pond";
        }
    }
}
